package org.example.mutithread.reentrantlock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Product {

    private String name;
    private String type;

    /**
     * lock 一个锁支持多个等待队列。 将生产者、消费者分别放到不同的等待队列，可以分别通知管理
     */
    private ReentrantLock lock = new ReentrantLock();// 锁

    private Condition pc = lock.newCondition();// 生产者等待队列
    private Condition cc = lock.newCondition();// 消费者等待队列

    /**
     * flag：true 已生产 false:未生产
     */
    private volatile boolean flag = false;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    /**
     * 生产商品
     * 
     * @param name
     * @param type
     */
    public void produce(String name, String type) {
        lock.lock();
        try {
            if (flag) {
                try {
                    pc.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.setName(name);
            this.setType(type);
            System.out.println(Thread.currentThread().getName() + " 生产了：" + this.toString());
            flag = true;
            cc.signal();
        } finally {
            lock.unlock();
        }

    }

    /**
     * 消费商品
     */
    public void consume() {
        lock.lock();
        try {
            if (!flag) {
                try {
                    cc.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + " 消费了：" + this.toString());
            flag = false;
            pc.signal();
        } finally {
            lock.unlock();
        }

    }

    @Override
    public String toString() {
        return "Product{" + "name='" + name + '\'' + ", type='" + type + '\'' + '}';
    }
}
